
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

package com.huawei.housekeeper.config.filter;

import com.huawei.housekeeper.model.Customer;
import com.huawei.housekeeper.utils.JwtTokenUtil;
import com.huawei.housekeeper.config.CustomerContext;

import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.log4j.Log4j2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.HttpHeaders;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * token鉴权
 *
 * @author lWX1128557
 * @since 2022-02-23
 */
@Log4j2
@RefreshScope
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Value("${jwt.tokenHead}")
    private String tokenHeader;

    @Autowired
    private HandlerExceptionResolver handlerExceptionResolver;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
        // 从http请求头的"Authorization"中拿token
        String jwtToken = request.getHeader(HttpHeaders.AUTHORIZATION);
        String userId = null;

        // 先判断token是否不为空且以tokenHeader开头
        if (jwtToken != null && jwtToken.startsWith(tokenHeader)) {
            // 截取token头部以后的信息得到荷载token(因为没有将token头一起签名)
            String token = jwtToken.substring(tokenHeader.length());
            String userName = null;
            try {
                // 使用JwtUtil解析token获取用户id
                userId = jwtTokenUtil.getUserIdFromToken(token);
                userName = jwtTokenUtil.getUserNameFromToken(token);
            } catch (ExpiredJwtException expiredJwtException) {
                handlerExceptionResolver.resolveException(request, response, null, expiredJwtException);
                return;
            } catch (Exception e) {
                handlerExceptionResolver.resolveException(request, response, null, e);
                log.error(e.getMessage(), e);
                return;
            }
            Customer customer = new Customer();
            customer.setUserId(userId);
            customer.setUserName(userName);
            CustomerContext.setCustomer(customer);
        }
        String method = request.getMethod(); // 获取请求方法
        log.info(request.getRequestURL() + ", userId: " + userId + ", method: " + method);
        filterChain.doFilter(request, response);
    }
}
